﻿using DL.Animation;
using DL.AudioSystem;
using DL.Characters.Player;
using DL.Characters.Player.FSM.Data;
using DL.Movement.Base;
using DL.Tools;
using Tools.Unilts;
using UnityEngine;

namespace DL.Movement
{
    public class PlayerMoveController : CharacterMoveControllerBase
    {
        public float OrientationSharpness = 10f;
        private float m_NextFoot;
        [SerializeField, Header("脚步声")] private float slowRunFoot;
        [SerializeField] private float fastRunFoot;
        
        [SerializeField,Header("激活方向指示器")] private bool enableDirectionDraw;

        protected Transform m_LookDirection;

        public RuntimeReusableData ReusableData;

        public void Init(Player player)
        {
            ReusableData = player.RuntimeReusableData;
            m_LookDirection = GameObject.FindWithTag("CameraLookTarget").transform;
            m_Animator = player.Animator;
            m_GroundedSensor = GetComponent<OnGroundedSensor>();
            m_CC = GetComponent<CharacterController>();
            m_Self = player.Self;
            
            Init();
        }

        protected override void Update()
        {
            base.Update();
            DrawDirection();
        }

        public void PlayFootstep()
        {
            if (CharacterIsOnGround && m_Animator.GetFloat(AnimatorParameter.Movement) > .5f &&
                m_Animator.CheckAnimationTag(AnimatorTag.Motion))
            {
                m_NextFoot -= Time.deltaTime;
                if (m_NextFoot <= 0)
                {
                    AudioManager.Inst.CreateAudio()
                        .WithSoundType(SoundType.Foot)
                        .WithRedomPitch()
                        .Play();
                    m_NextFoot = ReusableData.Running ? fastRunFoot : slowRunFoot;
                }
            }
            else
            {
                m_NextFoot = 0;
            }
        }

        private void DrawDirection()
        {
            if (enableDirectionDraw)
            {
                Debug.DrawRay(m_Self.position, m_MovementDirection.normalized,
                    Color.black);

                //这里只是输入方向，实际运动方向还没有被处理
                if (m_Animator.CheckAnimationTag(AnimatorTag.Motion))
                {
                    Debug.DrawRay(m_Self.position,
                        ReusableData.TargetDirection.normalized, Color.red);
                }
            }
        }

        float m_CurrentVelocity = 0;
        //********************************************************
        //转向 
        public void UpdateRotation(Vector2 movementDirection, ref Quaternion currentRotation, float deltaTime)
        {
            if (movementDirection.sqrMagnitude > 0f && OrientationSharpness > 0f)
            {
                Vector3 normalized = Vector3.Slerp(transform.forward, movementDirection,
                    1f - Mathf.Exp((0f - OrientationSharpness) * deltaTime)).normalized;
                currentRotation = Quaternion.LookRotation(normalized, transform.up);
            }
        }

        /// <summary>
        /// 按照输入方向获取旋转角度
        /// </summary>
        /// <param name="inputDirection"></param>
        /// <param name="applyRot">角色是否应用旋转</param>
        /// <returns></returns>
        public bool CalculateTurnAngles(Vector2 inputDirection,bool applyRot = true)
        {
            if (inputDirection == Vector2.zero)
            {
                ReusableData.CurrentAngle = float.NaN;
                ReusableData.RotationAngle = float.NaN;
                ReusableData.TargetAngle = 0;
                return false;
            }

            ReusableData.CurrentAngle = m_Self.eulerAngles.y;
            ReusableData.RotationAngle = Mathf.Atan2(inputDirection.x, inputDirection.y) * Mathf.Rad2Deg +
                                         m_LookDirection.eulerAngles.y;

            ReusableData.TargetDirection = Quaternion.Euler(0f,
                ReusableData.RotationAngle, 0f) * Vector3.forward;
            // Debug.Log(DevelopmentToos.ClampValueOn180(ReusableData.TargetAngle));
            if (applyRot)
            {
                m_Self.eulerAngles = Vector3.up *
                                     Mathf.SmoothDampAngle(
                                         m_Self.eulerAngles.y, ReusableData.RotationAngle,
                                         ref m_CurrentVelocity, ReusableData.RotationTime);
            }

            ReusableData.TargetAngle =
                DevelopmentToos.CalculateDeltaAngle(transform.forward, ReusableData.TargetDirection.normalized);
            // Debug.Log(ReusableData.TargetAngle);
            return true;
        }


        public void TurnTowards(Vector2 direction, float speed)
        {
            if (CalculateTurnAngles(direction))
            {
                TurnTowards(ReusableData.CurrentAngle, ReusableData.RotationAngle, speed);
            }
        }

        /// <summary>
        /// 调整转向
        /// </summary>
        /// <param name="currentAngle"></param>
        /// <param name="targetAngle"></param>
        /// <param name="deltaAngle">每Time.deltaTime调整的度数</param>
        public void TurnTowards(float currentAngle, float targetAngle, float deltaAngle)
        {
            currentAngle = Mathf.MoveTowardsAngle(currentAngle, targetAngle,
                deltaAngle * Time.deltaTime);
            var targetRotation = Quaternion.Euler(0, currentAngle, 0);
            m_Self.rotation = targetRotation;
        }

        /// <summary>
        /// 按照当前水平移动速度和预期速度进行插值插值获取转向速度
        /// </summary>
        /// <param name="minTurnSpeed"></param>
        /// <param name="maxTurnSpeed"></param>
        /// <param name="currentMoveSpeed"></param>
        /// <param name="desiredMoveSpeed"></param>
        /// <returns></returns>
        public float GetCurrentTurnSpeedLerp(float minTurnSpeed, float maxTurnSpeed, float currentMoveSpeed,
            float desiredMoveSpeed)
        {
            //这样调用保证在低速度下执行大角度旋转
            return Mathf.Lerp(maxTurnSpeed, minTurnSpeed, currentMoveSpeed / desiredMoveSpeed);
        }
        
    }
}